#rem
	Copyright (c) 2012 Peter J Rigby
	
	Permission is hereby granted, free of charge, to any person obtaining a copy
	of this software and associated documentation files (the "Software"), to deal
	in the Software without restriction, including without limitation the rights
	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the Software is
	furnished to do so, subject to the following conditions:
	
	The above copyright notice and this permission notice shall be included in
	all copies or substantial portions of the Software.
	
	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
	THE SOFTWARE.

#END

Import diddy
Import matrix
Import shape
Import collision

Const tlCAPTURE_SELF:Int = 0
Const tlCAPTURE_ALL:Int = 1
Const tlCAPTURE_NONE:Int = 2

Class tlGameObject
	
	Private
	
	Field name:string
	
	'vectors
	Field local_vec:tlVector2
	Field world_vec:tlVector2
	Field tiedvector:tlVector2
	
	Field scale_vec:tlVector2
	Field world_scale_vec:tlVector2
	
	Field zoom:Float = 1
	
	'matrices
	Field matrix:tlMatrix2				'A matrix to calculate entity rotation relative to the parent
	Field scale_matrix:tlMatrix2
	
	'colour
	Field red:Int = 255
	Field green:Int = 255
	Field blue:Int = 255
	Field alpha:Float = 1
	
	'image
	Field image:tlShape
	Field currentframe:Float
	''''Field currentanimseq:tlAnimationSequence
	Field framerate:Float
	Field animating:Int
	Field handle_vec:tlVector2
	Field autocenter:Int = True
	Field local_rotation:Float
	Field world_rotation:Float
	Field frames:Int
	Field iterations:Int
	Field iterationcount:Int
	Field blendmode:Int = AlphaBlend
	Field donotrender:Int

	'hierarchy
	Field parent:tlGameObject
	Field rootparent:tlGameObject
	Field children:List<tlGameObject>
	Field childcount:Int
	Field runchildren:Int
	Field relative:Int = True
	Field attached:Int
	Field rotate_vec:tlVector2 			'Vector formed between the parent and the children
	
	'tween values
	Field oldworld_vec:tlVector2
	Field oldworldscale_vec:tlVector2
	Field oldlocal_rotation:Float
	Field oldworld_rotation:Float
	Field oldcurrentframe:Float
	Field updatetime:Float = 30
	Field oldzoom:Float
	Field capturemode:Float
	
	'collision
	Field imagebox:tlBox
	Field imageboxtype:Int = tlBOX_COLLISION
	Field collisionbox:tlBox
	Field collisionboxtype:Int = tlBOX_COLLISION
	Field containingbox:tlBox
	Field rendercollisionbox:Int = False
	Field listenlayers:Int[]
	Field static:Int
	Field maxtlx:Float = $7fffffff
	Field maxtly:Float = $7fffffff
	Field maxbrx:Float = -$7fffffff
	Field maxbry:Float = -$7fffffff
	Field updatecontainingbox:Int

	
	'Age and status flags
	Field dob:Float
	Field age:Float
	Field dead:Int
	Field dying:Int
	Field destroyed:Int
	
	'components
	Field components:List<tlComponent> = New List<tlComponent>
	Field components_map:StringMap<tlComponent>
	
	Public
	
	'properties
	Method IsDestroyed:Int() Property
		Return destroyed
	End Method
	
	Method Dying:Int() Property
		Return dying
	End Method
	
	Method Dying(v:Int) Property
		dying = v
	End Method
	
	Method Dead:Int() Property
		Return dead
	End Method
	
	Method Dead(v:Int) Property
		dead = v
	End Method
	
	Method DoB:Int() Property
		Return dob
	End Method
	
	Method DoB(v:Int) Property
		dob = v
	End Method
	
	Method Destroyed:Int() Property
		Return destroyed
	End Method
	
	Method Destroyed(v:Int) Property
		destroyed = v
	End Method
	
	Method RenderCollisionBox(v:Bool = True) property
		rendercollisionbox = v
	End
	
	Method Name:String() Property
		Return name
	End
	
	Method Name(v:String) Property
		name = v
	End
	
	Method Zoom:Float() Property
		Return zoom
	End
	
	Method Zoom(v:float) Property
		zoom = v
	End
	
	Method OldZoom:Float() Property
		Return oldzoom
	End
	
	Method OldZoom(v:float) Property
		oldzoom = v
	End
	
	Method Matrix:tlMatrix2() Property
		Return matrix
	End
	
	Method Matrix(v:tlMatrix2) Property
		matrix = v
	End
	
	Method ScaleMatrix:tlMatrix2() Property
		Return scale_matrix
	End
	
	Method LocalVector:tlVector2() Property
		Return local_vec
	End
	
	Method WorldVector:tlVector2() Property
		Return world_vec
	End
	
	Method OldWorldVector:tlVector2() Property
		Return oldworld_vec
	End
	
	Method ScaleVector:tlVector2() Property
		Return scale_vec
	End
	
	Method WorldScaleVector:tlVector2() Property
		Return world_scale_vec
	End
	
	Method OldWorldScaleVector:tlVector2() Property
		Return oldworldscale_vec
	End
	
	Method HandleVector:tlVector2() Property
		Return handle_vec
	End
	
	Method HandleVector(v:tlVector2) Property
		handle_vec = v
	End
	
	Method LocalRotation:Float() Property
		Return local_rotation
	End
	
	Method LocalRotation(v:Float) Property
		local_rotation = v
	End
	
	Method Angle:Float() Property
		Return local_rotation
	End
	
	Method Angle(v:Float) Property
		local_rotation = v
	End
	
	Method WorldRotation:Float() Property
		Return world_rotation
	End
	
	Method WorldRotation(v:Float) Property
		world_rotation = v
	End
	
	Method OldLocalRotation:Float() Property
		Return oldlocal_rotation
	End
	
	Method OldLocalRotation(v:Float) Property
		oldlocal_rotation = v
	End
	
	Method OldWorldRotation:Float() Property
		Return oldworld_rotation
	End
	
	Method OldWorldRotation(v:Float) Property
		oldworld_rotation = v
	End
	
	Method RotateVector:tlVector2() Property
		Return rotate_vec
	End
	
	Method RotateVector(v:tlVector2) Property
		rotate_vec = v
	End
	
	Method DoNotRender:Int() Property
		Return donotrender
	End
	
	Method DoNotRender(v:Int) Property
		donotrender = v
	End
	
	Method UpdateContainerBox:Int() Property
		Return updatecontainingbox
	End
	
	Method UpdateContainerBox(v:Int) Property
		updatecontainingbox = v
	End
	
	Method Components:List<tlComponent>() Property
		Return components
	End
	
	Method ImageBox:tlBox() Property
		Return imagebox
	End
	
	Method ImageBox(v:tlBox) Property
		imagebox = v
	End
	
	Method ContainingBox:tlBox() Property
		Return containingbox
	End
	
	Method ContainingBox(v:tlBox) Property
		containingbox = v
	End
	
	Method Age:Int() Property
		Return age
	End
	
	Method Age(v:Int) Property
		age = v
	End
	
	Method AutoCenter:Int() Property
		Return autocenter
	End
	
	Method AutoCenter(v:Int) Property
		autocenter = v
	End
	
	Method BlendMode:Int() Property
		Return blendmode
	End
	
	Method BlendMode(v:Int) Property
		blendmode = v
	End
	
	Method Red:Int() Property
		Return red
	End
	
	Method Red(v:Int) Property
		red = v
	End
	
	Method Green:Int() Property
		Return green
	End
	
	Method Green(v:Int) Property
		green = v
	End
	
	Method Blue:Int() Property
		Return blue
	End
	
	Method Blue(v:Int) Property
		blue = v
	End
	
	Method Alpha:Float() Property
		Return alpha
	End
	
	Method Alpha(v:Float) Property
		alpha = v
	End	
	
	Method Image:tlShape() Property
		Return image
	End
	
	Method Image(v:tlShape) Property
		image = v
	End
	
	Method Frames:Int() Property
		Return frames
	End
	
	Method Frames(v:Int) Property
		frames = v
	End
	
	Method FrameRate:Float() Property
		Return framerate
	End
	
	Method FrameRate(v:Float) Property
		framerate = v
	End
	
	Method UpdateTime:Float() Property
		Return updatetime
	End
	
	Method UpdateTime(v:Float) Property
		updatetime = v
	End
	
	Method Animating:Int() Property
		Return animating
	End
	
	Method Animating(v:Int) Property
		animating = v
	End
	
	Method CurrentFrame:Float() Property
		Return currentframe
	End
	
	Method CurrentFrame(v:Float) Property
		currentframe = v
	End
	
	Method OldCurrentFrame:Float() Property
		Return oldcurrentframe
	End
	
	Method OldCurrentFrame(v:Float) Property
		oldcurrentframe = v
	End
	
	Method Relative:Int() Property
		Return relative
	End
	
	Method Relative(v:Int) Property
		relative = v
	End
	
	Method Parent:tlGameObject() Property
		Return parent
	End
	
	Method Parent(v:tlGameObject) Property
		parent = v
	End
	
	Method RootParent:tlGameObject() Property
		Return rootparent
	End
	
	Method RootParent(v:tlGameObject) Property
		rootparent = v
	End
	
	Method ChildCount:Int() Property
		Return childcount
	End
	
	Method ChildCount(v:Int) Property
		childcount = v
	End
	
	'methods
	Method New()
		local_vec = New tlVector2(0, 0)
		world_vec = New tlVector2(0, 0)
		
		oldworld_vec = New tlVector2(0, 0)
		oldworldscale_vec = New tlVector2(0, 0)
		
		scale_vec = New tlVector2(1, 1)
		world_scale_vec = New tlVector2(1, 1)
		
		handle_vec = New tlVector2(0, 0)
		
		children = New List<tlGameObject>
		
		'matrices
		matrix = New tlMatrix2
		scale_matrix = New tlMatrix2
		
		'compoents
		'components = New List<tlComponent>
		
		Capture()
		
	End Method
	
	'setters
	
	Method SetHandle(x:Int, y:Int)
		handle_vec.SetPosition(x, y)
	End
	
	Method SetImage(image:tlShape, collisiontype:Int = tlBOX_COLLISION, layer:Int = 0)
		Self.image = image
		frames = Self.image.Frames
		Select collisiontype
			Case tlPOLY_COLLISION
				SetImagePoly(GetWorldX(), GetWorldX(),[Float(-Self.image.Width) / 2, Float(-Self.image.Height) / 2,
					Float(-Self.image.Width) / 2, Float(Self.image.Height) / 2,
					Float(Self.image.Width) / 2, Float(Self.image.Height) / 2,
					Float(Self.image.Width) / 2, Float(-Self.image.Height) / 2], layer)
			Case tlCIRCLE_COLLISION
				SetImageCircle(GetWorldX(), GetWorldX(), Max(Self.image.Width / 2, Self.image.Height / 2), layer)
			Default
				SetImageBox(GetWorldX(), GetWorldX(), Self.image.Width, Self.image.Height, layer)
		End Select
	End Method
	
	Method SetImageBox(x:Float, y:Float, w:Float, h:Float, layer:Int = tlLAYER_0)
		imagebox = CreateBox(x, y, w, h, layer)
		imagebox.Data = Self
		imageboxtype = tlBOX_COLLISION
	End Method

	Method SetImageCircle(x:Float, y:Float, r:Float, layer:Int = tlLAYER_0)
		imagebox = CreateCircle(x, y, r, layer)
		imagebox.Data = Self
		imageboxtype = tlCIRCLE_COLLISION
	End Method

	Method SetImagePoly(x:Float, y:Float, verts:Float[], layer:Int = tlLAYER_0)
		imagebox = CreatePolygon(x, y, verts, layer)
		imagebox.Data = Self
		imageboxtype = tlPOLY_COLLISION
	End Method
	
	Method SetPosition(x:Float, y:Float)
		local_vec.SetPosition(x, y)
	End Method

	Method SetPositionVector(position:tlVector2)
		local_vec.SetPosition(position.x, position.y)
	End Method
	
	Method Move(x:Float, y:Float)
		local_vec.Move(x, y)
	End
	
	Method MoveVector(v:tlVector2)
		local_vec.Move(v.x, v.y)
	End
	
	Method TieToVector(vector:tlVector2)
		tiedvector = vector
	End
	
	Method UnTie()
		tiedvector = Null
	End
	
	Method SetScale(x:Float, y:Float)
		scale_vec.SetPosition(x, y)
	End Method

	'getters

	Method GetWorldX:Float()
		Return world_vec.x
	End Method

	Method GetWorldY:Float()
		Return world_vec.y
	End Method
	
	Method Capture()
		oldworld_vec.x = world_vec.x
		oldworld_vec.y = world_vec.y
		oldworldscale_vec.x = world_scale_vec.x
		oldworldscale_vec.y = world_scale_vec.y
		oldworld_rotation = world_rotation
		oldlocal_rotation = local_rotation
		oldcurrentframe = currentframe
		oldzoom = zoom
	End Method
	
	Method CaptureAll()
		Capture()
		For Local o:tlGameObject = EachIn children
			o.CaptureAll()
		Next
	End Method
	
	Method AddChild(o:tlGameObject)
		If o.parent
			o.parent.RemoveChild(o)
		End If
		children.AddLast(o)
		o.parent = Self
		o.AssignRootParent(o)
		o.attached = False
'		If Not _containingbox
'			_containingbox = CreateBox(0, 0, 1, 1)
'			_containingbox._data = Self
'			AssignMainBox()
'		End If
		childcount += 1
	End Method
	
	Method AttachChild(o:tlGameObject)
		If o.parent
			o.parent.RemoveChild(o)
		End If
		_children.AddLast(o)
		o.parent = Self
		o.AssignRootParent(o)
		o.attached = True
		childcount += 1
	End Method
	
	Method RemoveChild(o:tlGameObject)
		children.Remove(o)
		o.parent = Null
		o.rootparent = Null
		o.attached = False
		childcount -= 1
'		If Not childcount
'			containingbox = Null
'			AssignMainBox()
'		End If
	End Method
	
	Method Detatch()
		If parent parent.RemoveChild(Self)
	End Method
	
	Method ClearChildren()
		For Local o:tlGameObject = EachIn children
			o.Destroy()
		Next
		children.Clear()
		childcount = 0
	End Method
	
	Method GetChildCount:Int()
		Return childcount
	End Method

	Method GetChildren:List<tlGameObject>()
		Return children
	End Method
	
	Method KillChildren()
		For Local o:tlGameObject = EachIn children
			o.KillChildren()
			o.dead = True
		Next
	End Method
	
	Method Destroy()
		'debugstop
		parent = Null
		image = Null
		rootparent = Null
		If imagebox
			'imagebox.RemoveFromQuadTree()
			imagebox.Data = Null
			imagebox = Null
		End If
		If collisionbox
			'collisionbox.RemoveFromQuadTree()
			collisionbox.Data = Null
			collisionbox = Null
		End If
		If containingbox
			'containingbox.RemoveFromQuadTree()
			containingbox.Data = Null
			containingbox = Null
		End If
		For Local o:tlGameObject = EachIn children
			o.Destroy()
		Next
		If components
			For Local component:tlComponent = EachIn components
				component.Destroy()
			Next
		End If
		destroyed = True
	End Method
	
	Method AddComponent(component:tlComponent, last:Int = True)
		component.parent = Self
		If Not components components = New List<tlComponent>
		If Not components_map components_map = New StringMap<tlComponent>
		If last
			components.AddLast(component)
		Else
			components.AddFirst(component)
		End If
		components_map.Insert(component.name.ToUpper, component)
		component.Init()
	End Method
	
	Method GetComponent:tlComponent(name:String)
		Return tlComponent(components_map.ValueForKey(name.ToUpper))
	End Method
	
	Method Update()
	
		Select capturemode
			Case tlCAPTURE_SELF
				Capture()
			Case tlCAPTURE_ALL
				'capture all including children
				CaptureAll()
		End Select
						
		'update components
		UpdateComponents()
		
		If tiedvector
			local_vec.SetPositionByVector(tiedvector)
		EndIf
		
		'transform the object
		TForm()

		'update the children		
		UpdateChildren()
		
		'update the collision boxes
		If collisionbox UpdateCollisionBox()
		
		UpdateImageBox()
		
		If parent
			If containingbox
				parent.UpdateContainingBox(containingbox.tl_corner.x, containingbox.tl_corner.y, containingbox.br_corner.x, containingbox.br_corner.y)
			Else
				parent.UpdateContainingBox(imagebox.tl_corner.x, imagebox.tl_corner.y, imagebox.br_corner.x, imagebox.br_corner.y)
			End If
		End If
		If UpdateContainerBox ReSizeContainingBox()
		
		'animate the image
		Animate()
		
	End Method
	
	Method Render(tween:Float, origin:tlVector2 = Null, renderchildren:Int = True, screenbox:tlBox = Null)
		If image And Not donotrender
			If screenbox And imagebox
				If containingbox
					If Not screenbox.BoundingBoxOverlap(containingbox) Return
					Else
						If Not screenbox.BoundingBoxOverlap(imagebox) Return
				End If
			End If
			If Not origin Then origin = New tlVector2()
			If autocenter
				image.Image.SetHandle(image.Width / 2, image.Height / 2)
			Else
				image.Image.SetHandle(handle_vec.x, handle_vec.y)
			End If
			SetBlend blendmode
			Local tv:Float
			If Abs(oldworld_rotation - world_rotation) > 180
				tv = TweenValues(Abs(oldworld_rotation - 360), world_rotation, tween)
			Else
				tv = oldworld_rotation + (world_rotation - oldworld_rotation) * tween
			End If
			Rotate tv
			Local tx:Float = oldworldscale_vec.x + (world_scale_vec.x - oldworldscale_vec.x) * tween
			Local ty:Float = oldworldscale_vec.y + (world_scale_vec.y - oldworldscale_vec.y) * tween
			tv = oldzoom + (zoom - oldzoom) * tween
			If tv = 1
				Scale tx, ty
			Else
				Scale tx * tv, ty * tv
			End If
			SetColor red, green, blue
			SetAlpha alpha
			tv = currentframe
			DrawImage image.Image, (oldworld_vec.x + (world_vec.x - oldworld_vec.x) * tween) - origin.x, (oldworld_vec.y + (world_vec.y - oldworld_vec.y) * tween) - origin.y, tv
			If rendercollisionbox
				Scale 1, 1
				Rotate 0
				SetColor 255, 0, 255
				SetAlpha 0.5
				If collisionbox collisionbox.Draw(origin.x, origin.y, False)
				SetColor 255, 255, 0
				imagebox.Draw(origin.x, origin.y, True)
				SetColor 0, 255, 255
				If containingbox
					containingbox.Draw(origin.x, origin.y, False)
				End If
			End If
		End If
		If renderchildren
			For Local o:tlGameObject = EachIn children
				o.Render(tween, origin,, screenbox)
			Next
		End If
	End Method
	
	Method Animate()
		'update animation frame
'		If currentanimseq And _animating
			currentframe += framerate / updatetime
'		End If
	End Method
	
	Method UpdateImageBox()
		If Not static And imagebox
			imagebox.SetPosition(world_vec.x, world_vec.y)
			If oldworldscale_vec.x <> world_scale_vec.x Or oldworldscale_vec.y <> world_scale_vec.y Or oldzoom <> zoom
				If zoom = 1
					imagebox.SetScale(world_scale_vec.x, world_scale_vec.y)
				Else
					imagebox.SetScale(world_scale_vec.x * zoom, world_scale_vec.y * zoom)
				End If
			End If
			If imageboxtype = tlPOLY_COLLISION
				tlPolygon(imagebox).SetAngle(world_rotation)
			End If
			'imagebox.UpdateWithinQuadtree()
		End If
	End Method
	
	Method UpdateCollisionBox()
		AssertNotNull(collisionbox, "No collision box to update")
		If Not static
			collisionbox.SetPosition(world_vec.x, world_vec.y)
			If oldworldscale_vec.x <> world_scale_vec.x Or oldworldscale_vec.y <> world_scale_vec.y Or oldzoom <> zoom
				If zoom = 1
					collisionbox.SetScale(world_scale_vec.x, world_scale_vec.y)
				Else
					collisionbox.SetScale(world_scale_vec.x * zoom, world_scale_vec.y * zoom)
				End If
			End If
			If collisionboxtype = tlPOLY_COLLISION
				tlPolygon(collisionbox).SetAngle(world_rotation)
			End If
			'collisionbox.UpdateWithinQuadtree()
		End If
	End Method
	
	Method UpdateContainingBox(MaxTLX:Float, MaxTLY:Float, MaxBRX:Float, MaxBRY:Float)
		If containingbox
			maxtlx = Min(maxtlx, MaxTLX)
			maxtly = Min(maxtly, MaxTLY)
			maxbrx = Max(maxbrx, MaxBRX)
			maxbry = Max(maxbry, MaxBRY)
			updatecontainingbox = True
		End If
	End Method
	
	Method ReSizeContainingBox()
		If Not containingbox Return
		
		If imagebox
			maxtlx = Min(maxtlx, imagebox.tl_corner.x)
			maxtly = Min(maxtly, imagebox.tl_corner.y)
			maxbrx = Max(maxbrx, imagebox.br_corner.x)
			maxbry = Max(maxbry, imagebox.br_corner.y)
		End If
		
		Local width:Float = maxbrx - maxtlx
		Local height:Float = maxbry - maxtly
		
		containingbox.ReDimension(maxbrx - width, maxbry - height, width, height)
		'containingbox.UpdateWithinQuadtree()
		updatecontainingbox = False
		
		maxtlx = $7fffffff
		maxtly = $7fffffff
		maxbrx = -$7fffffff
		maxbry = -$7fffffff
	End Method
	
	Method AssignRootParent(o:tlGameObject)
		If parent
			parent.AssignRootParent(o)
		Else
			o.rootparent = Self
		End If
	End Method
	
	Method TForm()
		'set the matrix if it is relative to the parent
		If relative
			matrix.Set(Cos(local_rotation), Sin(local_rotation), -Sin(local_rotation), Cos(local_rotation))
		End If
		
		'calculate where the entity is in the world
		If parent And relative And Not attached
			zoom = parent.zoom
			matrix = matrix.Transform(parent.matrix)
			rotate_vec = parent.matrix.TransformVector(local_vec.Multiply(parent.world_scale_vec))
			If zoom = 1
				world_vec.SetPositionByVector(parent.world_vec.AddVector(rotate_vec))
			Else
				world_vec.SetPositionByVector(parent.world_vec.AddVector(rotate_vec.Scale(zoom)))
			End If
			world_rotation = parent.world_rotation + local_rotation
			world_scale_vec.SetPositionByVector(scale_vec.Multiply(parent.world_scale_vec))
		ElseIf parent And attached
			world_rotation = local_rotation
			world_scale_vec.SetPositionByVector(scale_vec)
			world_vec.SetPositionByVector(parent.world_vec)
		Else
			world_rotation = local_rotation
			world_scale_vec.SetPositionByVector(scale_vec)
			world_vec.SetPositionByVector(local_vec)
		End If
	End Method
	
	Method UpdateChildren()
		For Local o:tlGameObject = EachIn children
			o.Update()
		Next
	End Method
	
	Method UpdateComponents()
		For Local c:tlComponent = EachIn components
			c.Update()
			If destroyed Return
		Next
	End Method


End

Class tlComponent Abstract
	'Private
	
	Field parent:tlGameObject
	Field name:String
	
	'Public
	
	Method New(name:String)
		Self.name = name
	End Method
	
	Method Name(name:String) Property
		Self.name = name
	End
	
	Method Name:String() Property
		Return name
	End
	
	Method Update() Abstract
	
	#Rem
		Insert your Init code here. This is run when the component is added to a #tlGameObject
	#end 	
	Method Init()
		
	End Method
	
	Method Destroy()
		parent = Null
	End Method
	
	#Rem
	bbdocs: Get the parent of the component
	returns: #tlGameObject
	#end
	Method GetParent:tlGameObject()
		Return parent
	End Method
	
	Method Parent:tlGameObject() Property
		Return parent
	End
	
	Method Parent(v:tlGameObject) Property
		parent = v
	End
End